#pragma once
#include <iostream>
#include "utility/index.hpp"
#include "request_access/index.hpp"
#include "data_access/index.hpp"
#include "components/index.hpp"
#include "actions.hpp"

using namespace std;
using namespace utility;

namespace components2 {
    class SaleOrder : public components::EntityRequest {
    public:
        COMPONENT_INSTANCE_FUNCTION(SaleOrder);

        SaleOrder();

        any UpdateStatus();

        any Insert2();

        any CancelReview();

        any AddProductComplete();

        any AddInstall();

    private:
        EntityData getProductCompleteOrder();
        EntityData getInstallOrder();

        entity_access::EntityType *produceOrderEntity;
        entity_access::EntityType *productCompleteOrderEntity;
        entity_access::EntityType *installOrderEntity;
    };

    SaleOrder::SaleOrder() {
        SET_METHOD_ACTION(UpdateStatus);
        SET_METHOD_ACTION(Insert2);
        SET_METHOD_ACTION(CancelReview);
        SET_METHOD_ACTION(AddProductComplete);
        SET_METHOD_ACTION(AddInstall);
        produceOrderEntity = entity_access::GetEntityType("ProduceOrder");
        productCompleteOrderEntity = entity_access::GetEntityType("ProductCompleteOrder");
        installOrderEntity = entity_access::GetEntityType("InstallOrder");
    }

    std::any SaleOrder::UpdateStatus() {
        EntityData dict = Request->RequestEntity.GetEntityData(Entity->Name);

        auto oldEntityData = SelectEntityByPrimaryKey(QueryRequest->PrimaryKeyValue);
        if (oldEntityData.Empty()) return Request->GetMessageMap("销售订单不存在");

        auto msg = CompareVersion(dict, oldEntityData);
        if (!msg.empty()) return Request->GetMessageMap(msg);

        bool blSucceed = true;
        try {
            DataBase->BeginTransaction();

            blSucceed = Actions::UpdateStatusAndReview(shared_from_this(), produceOrderEntity, dict, 3);

            if (blSucceed) DataBase->CommitTransaction();
            else DataBase->RollbackTransaction();
        } catch (const std::exception &e) {
            DataBase->RollbackTransaction();
            throw MessageException(e.what(), "");
        }

        return GetSucceedMap(blSucceed);
    }

    any SaleOrder::Insert2() {
        return Actions::Insert2(shared_from_this(), 3);
    }

    any SaleOrder::CancelReview() {
        Actions::SetCancelReviewEntityData(shared_from_this());
        return UpdateStatus();
    }

    any SaleOrder::AddProductComplete() {
        auto dict = Request->RequestEntity.GetEntityData(Entity->Name);
        auto entityData = SelectEntityByPrimaryKey(QueryRequest->PrimaryKeyValue);
        if (entityData.Empty()) return Request->GetMessageMap("销售订单不存在");

        auto msg = CompareVersion(dict, entityData);
        if (!msg.empty()) return Request->GetMessageMap(msg);

        EntityData completeOrder = getProductCompleteOrder();
        bool blSucceed = true;

        try {
            DataBase->BeginTransaction();

            blSucceed = InsertEntity(productCompleteOrderEntity, completeOrder);
            if (blSucceed) blSucceed = components::EntityByComplexTypeOperation::EditDeleteComplexType(shared_from_this(), productCompleteOrderEntity, completeOrder, false);

            if (blSucceed) {
                EntityData updateEntityData;
                updateEntityData["UpdateDate"] = DateTime();
                updateEntityData["UpdateUser"] = Request->OperationUser;

                blSucceed = UpdateEntityByPrimaryKey(QueryRequest->PrimaryKeyValue, updateEntityData);
            }
            if (blSucceed)Actions::UpdateOrderCode(shared_from_this(), 6, completeOrder.Get("CompleteOrderId"));
            if (blSucceed) DataBase->CommitTransaction();
            else DataBase->RollbackTransaction();
        } catch (const std::exception &e) {
            DataBase->RollbackTransaction();
            throw MessageException(e.what(), "");
        }

        return GetSucceedMap(blSucceed);
    }

    EntityData SaleOrder::getProductCompleteOrder() {
        auto dict = Request->RequestEntity.GetEntityData(Entity->Name);
        EntityData data;

        data["SaleOrderId"] = dict["SaleOrderId"];
        data["CompleteDate"] = dict["CompleteDate"];
        data["ProduceEmployeeId"] = dict["ProduceEmployeeId"];
        data["Remark"] = dict["CompleteRemark"];
        data["CreateUser"] = Request->OperationUser;

        auto details = dict.GetEntityDataList("Details");

        vector<EntityData> detailList;
        for (auto &d: details) {
            auto num = d.GetFloat("CompleteNum");
            if (num != 0) {
                EntityData detail;
                detail["Num"] = d["CompleteNum"];
                detail["DisplayIndex"] = d["DisplayIndex"];
                detail["ProductId"] = d["ProductId"];
                detailList.emplace_back(detail);
            }
        }

        if (detailList.empty()) throw MessageException("产品明细完成数量不能都为0", "");

        data["Details"] = detailList;

        return data;
    }

    any SaleOrder::AddInstall() {
        auto dict = Request->RequestEntity.GetEntityData(Entity->Name);
        auto entityData = SelectEntityByPrimaryKey(QueryRequest->PrimaryKeyValue);
        if (entityData.Empty()) return Request->GetMessageMap("销售订单不存在");

        auto msg = CompareVersion(dict, entityData);
        if (!msg.empty()) return Request->GetMessageMap(msg);

        EntityData installOrder = getInstallOrder();
        bool blSucceed = true;

        try {
            DataBase->BeginTransaction();

            blSucceed = InsertEntity(installOrderEntity, installOrder);
            if (blSucceed) blSucceed = components::EntityByComplexTypeOperation::EditDeleteComplexType(shared_from_this(), installOrderEntity, installOrder, false);

            if (blSucceed) {
                EntityData updateEntityData;
                updateEntityData["UpdateDate"] = DateTime();
                updateEntityData["UpdateUser"] = Request->OperationUser;

                blSucceed = UpdateEntityByPrimaryKey(QueryRequest->PrimaryKeyValue, updateEntityData);
            }
            if (blSucceed)Actions::UpdateOrderCode(shared_from_this(), 7, installOrder.Get("InstallOrderId"));
            if (blSucceed) DataBase->CommitTransaction();
            else DataBase->RollbackTransaction();
        } catch (const std::exception &e) {
            DataBase->RollbackTransaction();
            throw MessageException(e.what(), "");
        }

        return GetSucceedMap(blSucceed);
    }

    EntityData SaleOrder::getInstallOrder() {
        auto dict = Request->RequestEntity.GetEntityData(Entity->Name);
        EntityData data;

        data["SaleOrderId"] = dict["SaleOrderId"];
        data["TakeEmployeeId"] = dict["TakeEmployeeId"];
        data["Remark"] = dict["Remark"];
        data["CreateUser"] = Request->OperationUser;
        data["InstallDate"] = dict["InstallDate"];
        if(dict.ContainsKey("InstallEmployeeIds")) {
            data["InstallEmployeeIds"] = dict["InstallEmployeeIds"];
            data["TotalAmount"] = dict["TotalAmount"];
            data["InstallAmount"] = dict["InstallAmount"];
            data["FreightAmount"] = dict["FreightAmount"];
            data["OtherAmount"] = dict["OtherAmount"];
            data["DiscountAmount"] = dict["DiscountAmount"];
        }

        auto details = dict.GetEntityDataList("Details");

        vector<EntityData> detailList;
        for (auto &d: details) {
            auto num = d.GetFloat("InstallNum");
            if (num != 0) {
                EntityData detail;
                detail["Num"] = d["InstallNum"];
                detail["DisplayIndex"] = d["DisplayIndex"];
                detail["ProductId"] = d["ProductId"];
                if(d.ContainsKey("Amount2")){
                    detail["InstallAmount"] = d["InstallAmount"];
                    detail["Amount"] = d["Amount2"];
                }
                detailList.emplace_back(detail);
            }
        }

        if (detailList.empty()) throw MessageException("产品明细提货数量不能都为0", "");

        data["Details"] = detailList;

        return data;
    }
}